﻿using UnityEngine;
using System.Collections;
using UnityEngine.Assertions;
using UnityEditor;

[behaviac.TypeMetaInfo("Tank", "Tank -> Entity")]
public class Tank : Entity {

    private TankData _tankData = null;
    public TankData tankData {
        get {
            return _tankData;
        }
    }

    private TankTurret _tankTurret = null;
    public new bool Init() {
        base.Init();

        GameObject tankTurretObj = transform.FindChild("Turret").gameObject;
        this._tankTurret = tankTurretObj.GetComponent<TankTurret>();
        Assert.IsTrue(this._tankTurret, "not find Turret");

        this._tankData = new TankData();
        this._tankData.Init();

        string btStr = "";
        string sceneName = Application.loadedLevelName;
        switch (sceneName) {
            case "Demo_01":
                btStr = "Tank_Fire_Random";
                break;
            case "Demo_02":
                btStr = "";
                break;
            default:
                btStr = "";
                break;
        }

        if (btStr.Length > 0) {
            bool ret = btload(btStr, true);
            if (ret) {
                btsetcurrent(btStr);
            }
        }
        return true;
    }

    public void Start() {
        this.TurretAngleUpdate();
    }

    public void TurretAngleUpdate() {
        if (this._tankTurret != null && this._tankData != null) {
            _tankTurret.transform.rotation = Quaternion.Euler(270, this._tankData.angleCurr, 0);
        }
    }

    public Vector3 tankCameraPoint {
        get {
            return _tankTurret.cameraPoint;
        } 
    }

	public void Tick () {
        btexec();
        float speeds = 3.0f;
        float distance = speeds * GameScene.instance.gameData.tickTime;
        if (Input.GetKey(KeyCode.UpArrow)) {
            transform.position += Vector3.forward * distance;
        } else if (Input.GetKey(KeyCode.DownArrow)) {
            transform.position += Vector3.back * distance;
        }
	}

    public bool IsCanFire() {
        GameData gameData = GameScene.instance.gameData;
        if (this._tankData.fireCount == 0 || this._tankData.fireLastTime + this._tankData.fireCD <= gameData.gameTime)
            return true;
        return false;
    }

    public bool Fire() {
        if (!this.IsCanFire() || !this.SpawnBullet())
            return false;
        this._tankData.fireCount++;
        this._tankData.fireLastTime = GameScene.instance.gameData.gameTime;

        return true;
    }

    public bool SpawnBullet() {
        GameObject gameObj = Resources.Load("Prefabs/Bullet") as GameObject;
        GameObject obj = Instantiate(gameObj) as GameObject;
        Bullet bullet = obj.GetComponent<Bullet>();
        BulletData bulletData = bullet.bulletData;
        bulletData.position = _tankTurret.firePoint;
        bulletData.direction = Quaternion.Euler(0, this._tankData.angleCurr, 0) * Vector3.forward;
        return GameScene.instance.AddBullet(bullet);
    }


    [behaviac.MethodMetaInfo()]
    public behaviac.EBTStatus TurretAngleRotating(float angle) {
        float tickTime = GameScene.instance.gameData.tickTime;
        float angleDifference = Mathf.DeltaAngle(this._tankData.angleCurr, angle);
        float angleRotation = Mathf.Min(Mathf.Abs(angleDifference), this._tankData.angleSpeed * tickTime);
        if (angleDifference < 0) {
            angleRotation = -angleRotation;
        }
        this._tankData.angleCurr += angleRotation;
        this.TurretAngleUpdate();

        if (Mathf.Abs(Mathf.DeltaAngle(this._tankData.angleCurr, angle)) > 0.01f)
            return behaviac.EBTStatus.BT_RUNNING;
        return behaviac.EBTStatus.BT_SUCCESS;
    }

    [behaviac.MethodMetaInfo()]
    public behaviac.EBTStatus TankFire() {
        return this.Fire() ? behaviac.EBTStatus.BT_SUCCESS : behaviac.EBTStatus.BT_FAILURE;
    }

    [behaviac.MethodMetaInfo()]
    public behaviac.EBTStatus TankWaitFireCD() {
        return this.IsCanFire() == true ? behaviac.EBTStatus.BT_SUCCESS : behaviac.EBTStatus.BT_RUNNING;
    }
}
